#!/usr/bin/env python
#
# Copyright (C) 2005-2020 ABINIT Group (Yann Pouillon)
#
# This file is part of the ABINIT software package. For license information,
# please see the COPYING file in the top-level directory of the ABINIT source
# distribution.
#
from __future__ import print_function, division, absolute_import #, unicode_literals

try:
    from ConfigParser import ConfigParser,NoOptionError
except ImportError:
    from configparser import ConfigParser,NoOptionError
from time import gmtime,strftime

try:
    from commands import getoutput
except:
    from subprocess import getoutput
import os
import re
import sys

class MyConfigParser(ConfigParser):

  def optionxform(self,option):
    return str(option)

# ---------------------------------------------------------------------------- #

#
# Subroutines
#

# Macro header
def macro_header(name,stamp):

  return """# Generated by %s on %s

#
# Per-directory optimization support
#

#
# IMPORTANT NOTE
#
# This file has been automatically generated by the %s
# script. If you try to edit it, your changes will systematically be
# overwritten.
#



# ABI_OPTFLAGS_DIRS(FCFLAGS_OPTIM)
# --------------------------------
#
# Initializes optimization flags on a per-directory basis. Currently
# limited to Fortran.
#
AC_DEFUN([ABI_OPTFLAGS_DIRS],[
  dnl Check arguments
  m4_if([$1], , [AC_FATAL([$0: missing argument 1])])dnl

  AC_MSG_CHECKING([whether to apply per-directory optimizations])
  if test "${enable_optim}" = "no" -o "${FCFLAGS}" != ""; then
    AC_MSG_RESULT([no])
  else
    AC_MSG_RESULT([yes])
  fi

  dnl Init config.optim
  echo "optim_dumper_template='${abinit_srcdir}/shared/common/src/14_hidewrite/m_optim_dumper.F90.in'" > config.optim
  echo "optim_dumper_output='${abinit_builddir}/shared/common/src/14_hidewrite/m_optim_dumper.F90'" >> config.optim

  dnl Set default
  fcflags_opt_default="$1"
  echo "fcflags_opt_default='${fcflags_opt_default}'" >>config.optim
  fcflags_opt_dirlist=""
  AC_SUBST(fcflags_opt_default)
@OPTFLAGS@
  echo "fcflags_opt_dirlist='${fcflags_opt_dirlist}'" >>config.optim
]) # ABI_OPTFLAGS_DIRS\n"
""" % (name,stamp,name)



# Variable test
def macro_optflags(name):

  return """
  dnl %s library
  if test "${FCFLAGS}" = ""; then
    if test "${fcflags_opt_%s}" = "" -o "${enable_optim}" = "no"; then
      fcflags_opt_%s="${fcflags_opt_default}"
    else
      AC_MSG_NOTICE([optimization for %s is ${fcflags_opt_%s}])
      echo "fcflags_opt_%s='${fcflags_opt_%s}'" >>config.optim
      fcflags_opt_dirlist="${fcflags_opt_dirlist} %s"
    fi
  else
    if test "${fcflags_opt_%s}" != ""; then
      fcflags_opt_%s=""
      AC_MSG_NOTICE([fcflags_opt_%s overriden by FCFLAGS])
    fi
  fi
  AC_SUBST(fcflags_opt_%s)
""" % (name,name,name,name,name,name,name,name,name,name,name,name)



# ---------------------------------------------------------------------------- #

#
# Main program
#

# Initial setup
my_name   = "make-macros-dirflags"
my_config = "config/specs/corelibs.conf"
my_output = "config/m4/auto-dirflags.m4"

# Check if we are in the top of the ABINIT source tree
if ( not os.path.exists("configure.ac") or
     not os.path.exists("src/98_main/abinit.F90") ):
  print("%s: You must be in the top of an ABINIT source tree." % my_name)
  print("%s: Aborting now." % my_name)
  sys.exit(1)

# Read config file(s)
if ( not os.path.exists(my_config) ):
  print("%s: Could not find config file (%s)." % (my_name,cnf_file))
  print("%s: Aborting now." % my_name)
  sys.exit(2)

# What time is it?
now = strftime("%Y/%m/%d %H:%M:%S +0000",gmtime())

# Init corelibs
lib_cnf = MyConfigParser()
lib_cnf.read(my_config)
abinit_corelibs = lib_cnf.sections()
abinit_corelibs.sort()

# FIXME: find external libraries from binaries
ext_libs = list()
bin_cnf = MyConfigParser()
bin_cnf.read("config/specs/binaries.conf")
for main_bin in bin_cnf.sections():
  if ( bin_cnf.has_option(main_bin,"dependencies") ):
    ext_libs += bin_cnf.get(main_bin,"dependencies").split()
ext_libs = sorted(list(set(ext_libs)))
ext_libs.remove("fft")
ext_libs.remove("gpu")
ext_libs.remove("mpi")

# Init
mac = ""

# Process each library and binary dir
for lib in ext_libs + abinit_corelibs + ["98_main"]:
  mac += macro_optflags(lib)

# Write configuration dumper (for debugging)
dumper = open("config.dump.in","a")
dumper.write("# Fallbacks variables (script: %s)\n" % (my_name))
for fbk in ext_libs:
  dumper.write("FCFLAGS_%s_EXT=\"@FCFLAGS@ @fcflags_opt_%s@\"\n" % \
    (fbk.upper(),fbk))
dumper.write("\n")
dumper.close()

# The end
mac = re.sub("@OPTFLAGS@",mac,macro_header(my_name,now))
m4 = open(my_output, "wt")
m4.write(mac)
m4.close()

tmp = getoutput("./config/scripts/add-header-typed Autoconf %s" % (my_output))
if ( tmp != "" ):
  print(tmp)
